2 using System
.Collections
.Generic
;
4 namespace EZObjectPools
6 [AddComponentMenu("EZ Object Pool/Object Pool")]
7 public class EZObjectPool
: MonoBehaviour
9 static Dictionary
<string, EZObjectPool
> SharedPools
= new Dictionary
<string, EZObjectPool
>();
10 static GameObject Marker
;
13 /// The template GameObject this pool uses.
15 public GameObject Template
;
17 /// The name of this pool.
19 public string PoolName
;
21 /// The list of all objects owned by this pool.
23 public List
<GameObject
> ObjectList
;
25 /// Should this pool automatically resize when empty?
27 public bool AutoResize
= false;
29 /// The default pool size.
31 public int PoolSize
= 100;
33 /// Only used for pools created in the editor. Should this pool be instantiated when the scene loads?
35 public bool InstantiateOnAwake
;
37 /// Only used for pools created in the editor. Any scripts that request a pool with the same name as this one will recieve this pool.
42 /// Creates a new Object Pool and returns a reference to the created pool.
44 /// <param name="template">The template this pool will make copies of.</param>
45 /// <param name="name">The name of this pool. Only used to identify it in the hierarchy.</param>
46 /// <param name="size">How many objects will be pre-instantiated.</param>
47 /// <param name="autoResize">Should this pool create new objects if it is empty?</param>
48 /// <param name="instantiateImmediate">Should this pool be instantiated immediately?</param>
49 /// <param name="shared">Should pools with the same name be shared?</param>
50 /// <returns>A reference to the created pool.</returns>
51 public static EZObjectPool
CreateObjectPool(GameObject template
, string name
, int size
, bool autoResize
, bool instantiateImmediate
, bool shared
)
55 Marker
= new GameObject("EZ Object Pools Container");
61 if (SharedPools
.ContainsKey(name
))
62 return SharedPools
[name
];
65 GameObject g
= new GameObject(name
);
66 EZObjectPool pool
= g
.AddComponent
<EZObjectPool
>();
67 pool
.InstantiateOnAwake
= false;
68 pool
.SetProperties(template
, size
, name
, autoResize
);
69 SharedPools
.Add(name
, pool
);
71 if (instantiateImmediate
)
72 pool
.InstantiatePool();
74 g
.transform
.parent
= Marker
.transform
;
81 GameObject g
= new GameObject(name
);
82 EZObjectPool pool
= g
.AddComponent
<EZObjectPool
>();
83 pool
.InstantiateOnAwake
= false;
84 pool
.SetProperties(template
, size
, name
, autoResize
);
86 if (instantiateImmediate
)
87 pool
.InstantiatePool();
89 g
.transform
.parent
= Marker
.transform
;
99 Marker
= new GameObject("EZ Object Pools Container");
103 if (InstantiateOnAwake
)
105 ObjectList
= new List
<GameObject
>(PoolSize
);
106 AvailableObjects
= new List
<GameObject
>(PoolSize
);
112 SharedPools
.Add(this.PoolName
, this);
116 #region Instance Functions
118 List
<GameObject
> AvailableObjects
;
121 /// Set the properties of the pool.
123 /// <param name="objectTemplate">The template object to clone.</param>
124 /// <param name="size">The amount of clones to create</param>
125 /// <param name="name">Name of this pool</param>
126 /// <param name="autoResize">Should new objects be instantiated if the pool is empty?</param>
127 public void SetProperties(GameObject objectTemplate
, int size
, string name
, bool autoResize
)
129 Template
= objectTemplate
;
131 ObjectList
= new List
<GameObject
>(size
);
132 AvailableObjects
= new List
<GameObject
>(size
);
134 this.AutoResize
= autoResize
;
138 /// Creates the set number of objects at the world origin (0,0,0) and sets them to inactive. Deletes any previous objects.
140 public void InstantiatePool()
142 if (Template
== null)
144 Debug
.LogError("EZ Object Pool: " + name
+ ": Template GameObject is null! Make sure you assigned a template either in the inspector or in your scripts.");
150 for (int i
= 0; i
< PoolSize
; i
++)
152 GameObject g
= NewActiveObject();
159 /// Attempts to get the next available object in the pool. Will return true and assign a reference to the out variable if successful.
161 /// <param name="pos">The position to spawn the object at.</param>
162 /// <param name="rot">The rotation to spawn the object at.</param>
163 /// <param name="obj">A reference to the GameObject being spawned.</param>
164 /// <returns>Returns true if an object was successfully retrieved, False if not.</returns>
165 public bool TryGetNextObject(Vector3 pos
, Quaternion rot
, out GameObject obj
)
167 if (ObjectList
.Count
== 0)
169 Debug
.LogError("EZ Object Pool " + PoolName
+ ", the pool has not been instantiated but you are trying to retrieve an object!");
172 int lastIndex
= AvailableObjects
.Count
- 1;
174 if (AvailableObjects
.Count
> 0)
176 if (AvailableObjects
[lastIndex
] == null)
178 Debug
.LogError("EZObjectPool " + PoolName
+ " has missing objects in its pool! Are you accidentally destroying any GameObjects retrieved from the pool?");
183 AvailableObjects
[lastIndex
].transform
.position
= pos
;
184 AvailableObjects
[lastIndex
].transform
.rotation
= rot
;
185 AvailableObjects
[lastIndex
].SetActive(true);
186 obj
= AvailableObjects
[lastIndex
];
187 AvailableObjects
.RemoveAt(lastIndex
);
193 GameObject g
= NewActiveObject();
194 g
.transform
.position
= pos
;
195 g
.transform
.rotation
= rot
;
208 /// Attempts to get the next available object in the pool. Will do nothing if the pool is empty.
210 /// <param name="pos">The position to put the object at.</param>
211 /// <param name="rot">The rotation to put the object at.</param>
212 public void TryGetNextObject(Vector3 pos
, Quaternion rot
)
214 if (ObjectList
.Count
== 0)
216 Debug
.LogError("EZ Object Pool " + PoolName
+ ", the pool has not been instantiated but you are trying to retrieve an object!");
219 int lastIndex
= AvailableObjects
.Count
- 1;
221 if (AvailableObjects
.Count
> 0)
223 if (AvailableObjects
[lastIndex
] == null)
225 Debug
.LogError("EZObjectPool " + PoolName
+ " has missing objects in its pool! Are you accidentally destroying any GameObjects retrieved from the pool?");
229 AvailableObjects
[lastIndex
].transform
.position
= pos
;
230 AvailableObjects
[lastIndex
].transform
.rotation
= rot
;
231 AvailableObjects
[lastIndex
].SetActive(true);
232 AvailableObjects
.RemoveAt(lastIndex
);
238 GameObject g
= NewActiveObject();
239 g
.transform
.position
= pos
;
240 g
.transform
.rotation
= rot
;
245 GameObject
NewActiveObject()
247 GameObject g
= (GameObject
)Instantiate(Template
);
248 g
.transform
.parent
= transform
;
250 PooledObject p
= g
.GetComponent
<PooledObject
>();
255 g
.AddComponent
<PooledObject
>().ParentPool
= this;
261 /// Destroys all objects that are a part of this pool.
263 public void ClearPool()
265 for (int i
= 0; i
< ObjectList
.Count
; i
++)
267 Destroy(ObjectList
[i
]);
271 AvailableObjects
.Clear();
275 /// Destroys this pool.
277 /// <param name="deleteActiveObjects">Should it delete any active GameObjects that are part of this pool?</param>
278 public void DeletePool(bool deleteActiveObjects
)
280 for (int i
= 0; i
< ObjectList
.Count
; i
++)
282 if (!ObjectList
[i
].activeInHierarchy
|| (ObjectList
[i
].activeInHierarchy
&& deleteActiveObjects
))
283 Destroy(ObjectList
[i
]);
288 /// Adds the given GameObject to the Available Objects list.
290 /// <param name="obj">The GameObject to add.</param>
291 public void AddToAvailableObjects(GameObject obj
)
293 AvailableObjects
.Add(obj
);
301 /// Gets the number of currently active objects.
303 public int ActiveObjectCount()
305 return ObjectList
.Count
- AvailableObjects
.Count
;
309 /// Gets the number of currently available objects.
311 public int AvailableObjectCount()
313 return AvailableObjects
.Count
;